#ifndef __ming_fyp_FypApp_h__
#define __ming_fyp_FypApp_h__

//------------------------------------------------------------------------------
// header includes
#include "fyp/app/DxApp.h"
#include "fyp/render/RenderedTexture.h"
#include "fyp/core/Vec.h"
#include <vector>

//------------------------------------------------------------------------------
namespace ming
{
namespace fyp
{
	namespace render
	{
		class IRenderer;
		class TResourceFactory;
	}

	class TGuiManager;
	class TObjectManager;
	class TCamera;
	class TResourcePool;
	class IShadowAlgorithm;

	//--------------------------------------------------------------------------
	class TFypApp : public app::IDxApp
	{
	public:
		friend class TFypAppGui;

		//------------------------------
		// #cstor & #dstor
		TFypApp();
		~TFypApp();
		
		//------------------------------
		// external operations
		virtual WndInfo GetAppWndInfo();

		virtual void SetDevice(IDirect3DDevice9* device);

		virtual bool AcceptDevice(
			D3DCAPS9* caps,
			D3DFORMAT adapterFmt,
			D3DFORMAT backBufFmt);

		virtual void RecreateResources(
			IDirect3DDevice9* device,
			const D3DSURFACE_DESC* backBufDesc);

		virtual void DestroyResources();

		virtual void Render(IDirect3DDevice9* device, float dt);

		virtual void HandleMouseEvent(
			bool leftBtnDown,
			bool rightBtnDown,
			bool midBtnDown,
			int wheelDelta,
			int xPos,
			int yPos);

		virtual void HandleKeyboardEvent(
			unsigned int charCode,
			bool keyDown,
			bool altDown);

		virtual void HandleWindowEvent(
			HWND hWnd,
			UINT uMsg,
			WPARAM wParam,
			LPARAM lParam,
			bool* pbNoFurtherProcessing);

	private:
		//------------------------------
		// internal attributes
		D3DSURFACE_DESC mBackBufDesc;
		
		render::IRenderer *mRenderer;
		render::TResourceFactory *mResFactory;

		TGuiManager *mGuiMgr;
		TObjectManager *mObjMgr;
		TResourcePool *mResPool;
		TCamera *mEyeCam;
		TCamera *mLightCam;
		TCamera *mActiveCam;
		bool mLightRotate;

		TFypAppGui *mGui;

		TVec3 mMouseDelta;

		tuple<TVec4, TVec4> mBgColor;

		size_t mCurrAlgorithm;
		std::vector<IShadowAlgorithm*> mAlgorithms;

		size_t mCurrShadowMapSize;
		std::vector<size_t> mShadowMapSizes;
		float mShadowMapBias;

		enum TShaderParams;
		
		//------------------------------
		// internal operations
		void RegisterShaderParams();
		void UpdateShaderParams();
		
		void StepEye(float dt);
		
		void RenderScene();
		void RenderVisualizations();

		void NextAlgorithm();
		void SetAlgorithm(size_t index);
		void InitCurrentAlgorithm();
		void FinalCurrentAlgorithm();

		size_t CurrentShadowMapSize();
		void NextShadowMapSize();
		void SetShadowMapSize(size_t index);

		void UpdateDebugText();
	};
	
	//--------------------------------------------------------------------------
}
}


#endif	//__ming_fyp_FypApp_h__